using Hydrogen.ULib.UINavigation;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

namespace Hydrogen.ULib
{
    public class SampleScene : MonoBehaviour
    {
        [SerializeField]
        private UINavGroup _root;
        [SerializeField]
        private UINavNode _defaultSelected;

        public RectTransform FK => this._fk;
        [SerializeField]
        private RectTransform _fk;

        public InputActionMap Map;

        private List<ContinuousHoldInteractions> _interactions;

        private void Start()
        {
            this._root?.Select();
            this._root?.UpdateNodeColl();

            Map.Enable();

            _interactions = new List<ContinuousHoldInteractions>
            {
                new ContinuousHoldInteractions(Map.FindAction("Up"), () => _root?.Move(Arrow.Up)),
                new ContinuousHoldInteractions(Map.FindAction("Down"), () => _root?.Move(Arrow.Down)),
                new ContinuousHoldInteractions(Map.FindAction("Left"), () => _root?.Move(Arrow.Left)),
                new ContinuousHoldInteractions(Map.FindAction("Right"), () => _root?.Move(Arrow.Right)),
            };
            
            Map.FindAction("Submit").performed += KeyPerformed_Submit;
            Map.FindAction("Cancel").performed += KeyPerformed_Cancel;
        }

        private void KeyPerformed_Cancel(InputAction.CallbackContext context)
        {
            _root?.Cancel();
        }

        private void KeyPerformed_Submit(InputAction.CallbackContext context)
        {
            _root?.Submit();
        }


        private void Update()
        {
            if(_interactions != null && _interactions.Count > 0)
            {
                foreach (var item in _interactions)
                {
                    item?.Update();
                }
            }
        }

        public class ContinuousHoldInteractions
        {
            private float _interval;
            private float _lastKeyTime;
            private const float _minInterval = 0.05f;
            private const float _maxInterval = 0.25f;

            private Action _preformed;

            public ContinuousHoldInteractions(InputAction action,Action performed)
            {
                if (action != null)
                {
                    action.performed += ActionPerformed;
                    action.canceled += ActionCanceled;
                }
                this._preformed = performed;
            }

            private bool _isHold;
            private void ActionPerformed(InputAction.CallbackContext obj)
            {
                _preformed?.Invoke();
                _interval = _maxInterval;
                _lastKeyTime = Time.time;
                _isHold = true;
            }

            private void ActionCanceled(InputAction.CallbackContext context)
            {
                _isHold = false;
            }

            public void Update()
            {
                if (!_isHold) return;
                if (Time.time - _lastKeyTime < _interval) return;

                _preformed?.Invoke();
                _interval = Mathf.Max(_minInterval, _interval - 0.05f);
                _lastKeyTime = Time.time;
            }
        }
    }
}
